package service

import (
	"admin100/app/dao"
	"admin100/app/dao/centerdao"
	"admin100/app/dao/gamedao"
	"admin100/app/model"
	"admin100/app/model/gamemodel"
	"admin100/app/service/centerservice"
	"admin100/app/service/commonservice"
	"admin100/library/define"
	"admin100/library/define/defErr"
	"admin100/library/utils"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"

	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/gtime"
)

var Tool = &toolService{}

type toolService struct{}

func (s *toolService) GetIpLocation(ip string) string {
	//url := "http://ip.taobao.com/service/getIpInfo.php?ip=" + ip
	url := "http://118.25.181.121：7060/ip?ip=" + ip
	var result struct {
		//Code int
		Ret  int
		Data struct {
			Country string
			Region  string
			City    string
			Isp     string
		}
	}
	resp, err := http.Get(url)
	defErr.IfPanic(err, define.UnKnow)

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	defErr.IfPanic(err, define.UnKnow)
	//g.Log().Info("result:%v", string(body))

	err = json.Unmarshal(body, &result)
	defErr.IfPanic(err, define.UnKnow)

	if result.Ret == 0 {
		if result.Data.Country == "中国" {
			return result.Data.Region + "." + result.Data.City + " " + result.Data.Isp
		}
		return result.Data.Country + "." + result.Data.Region + "." + result.Data.City + " " + result.Data.Isp
	}
	return define.GotMsg(define.UnKnow)
}

func (s *toolService) GetForbidLogList(req *model.ForbidLogListReq) ([]*model.ForbidLog, int) {
	var (
		column = dao.ForbidLog.Columns
	)

	m := dao.ForbidLog.WhereValNotEmpty(g.Map{
		column.PlatformId: req.PlatformId,
		column.ServerId:   req.ServerId,
	})
	if req.PlayerId > 0 {
		m = m.Where(column.PlayerId, req.PlayerId)
	}
	m1 := m.Clone()
	m.M = m.M.Order(column.Time + " desc")
	data, err := m.Page(req.Cur, req.PNum).FindAll()
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}
	total, err := m1.Count()
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}

	var (
		uids []int
	)
	for _, v := range data {
		uids = append(uids, v.UserId)
	}
	us := dao.MyadminUser.GetUserList(uids)
	for _, v := range data {
		if e, ok := us[v.UserId]; ok {
			v.PlayerName = e.Name
		}

		node := centerservice.CGameServer.FetchNodeStrByPtIdAndSid(req.PlatformId, v.ServerId)
		gamePlayer := gamedao.NewPlayerDao(node)
		curPlayerName := gamePlayer.GetPlayerName_2(v.ServerId, int(v.PlayerId))
		v.PlayerName = curPlayerName
	}

	return data, total
}

func (s *toolService) GetBackgroundChargeLogList(req *model.BackgroundChargeLogReq) ([]*model.BackgroundChargeLog, int) {
	var (
		column = dao.BackgroundChargeLog.Columns
	)

	m := dao.BackgroundChargeLog.WhereValNotEmpty(g.Map{
		column.PlatformId: req.PlatformId,
		column.ServerId:   req.ServerId,
	})
	if req.StartTime > 0 {
		m.Where(column.Time+" between ? and ?", req.StartTime, req.EndTime)
	}
	if req.PlayerId > 0 {
		m = m.Where(column.PlayerId, req.PlayerId)
	}
	m1 := m.Clone()
	m.M = m.M.Order(column.Time + " desc")
	data, err := m.Page(req.Cur, req.PNum).FindAll()
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}
	if data == nil {
		return nil, 0
	}
	total, err := m1.Count()
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}

	var (
		uids []int
	)
	for _, v := range data {
		uids = append(uids, v.UserId)
	}
	us := dao.MyadminUser.GetUserList(uids)
	for _, v := range data {
		if e, ok := us[v.UserId]; ok {
			v.UserName = e.Name
		}

		node := centerservice.CGameServer.FetchNodeStrByPtIdAndSid(req.PlatformId, v.ServerId)
		gamePlayer := gamedao.NewPlayerDao(node)
		curPlayerName := gamePlayer.GetPlayerName_2(v.ServerId, int(v.PlayerId))
		v.PlayerName = curPlayerName

	}

	return data, total

}

func (s *toolService) BackgrounRecharge(sNode string, req *model.RechargeReq, player *gamemodel.Player, curUser *model.MyadminUser) {

	var result struct {
		Code    int
		Message string
	}

	ga := centerdao.GlobalAccount.GetGlobalAccount(req.PlatformId, player.AccId)
	if ga.Type == 0 {
		defErr.Panic(define.Fail, fmt.Sprintf("后台充值失败: %s.%s 不是内部帐号", req.ServerId, player.Nickname))
	}

	args := fmt.Sprintf("player_id=%d&game_charge_id=0&charge_item_id=%d&item_count=%d&partid=%s&charge_type=%s&gm_id=%s",
		player.Id,
		req.ItemId,
		req.ChargeValue,
		req.PlatformId,
		req.ChargeType,
		curUser.Account,
	)
	sign := utils.String2md5(args + "fa9274fd68cf8991953b186507840e5e")

	url := centerservice.CGameNode.GetGameURLByNode(sNode) + "/gm_charge?" + args + "&sign=" + sign
	resp, err := http.Get(url)
	defErr.IfPanic(err, define.ReqInvokeFail)

	body, err := ioutil.ReadAll(resp.Body)
	defErr.IfPanic(err, define.ReadReqRetFail)

	err = json.Unmarshal(body, &result)
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}

	if result.Code == 0 {
		backgroundChargeLog := &model.BackgroundChargeLog{
			PlatformId:  req.PlatformId,
			ServerId:    string(player.ServerId),
			PlayerId:    uint(req.PlayerId),
			Time:        int(gtime.Timestamp()),
			ChargeType:  req.ChargeType,
			ChargeValue: req.ChargeValue,
			ItemId:      req.ItemId,
			UserId:      curUser.Id,
		}
		_, err := dao.BackgroundChargeLog.FieldsEx("playerName, userName").Save(backgroundChargeLog)
		if err != nil {
			defErr.Panic(define.DataOptFail, err.Error())
		}
	}

}

func (s *toolService) GetPlayerByPlatformIdAndNickname(req *gamemodel.OneReq) *gamemodel.Player {
	sid, nick := commonservice.GamePlayer.SplitPlayerName(req.PlayerName)
	node := centerservice.CGameServer.FetchNodeStrByPtIdAndSid(req.PlatformId, sid)

	gameDb := gamedao.NewPlayerDao(node)
	player, err := gameDb.Where(g.Map{
		gameDb.Columns.ServerId: sid,
		gameDb.Columns.Nickname: nick,
	}).FindOne()
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}
	if player == nil {
		return nil
	}

	playerPropDb := gamedao.NewPlayerPropDao(node)

	player.Nickname = req.PlayerName
	ga := centerdao.GlobalAccount.GetGlobalAccount(req.PlatformId, player.AccId)
	player.Type = ga.Type
	player.AccountForbidType = ga.ForbidType
	player.AccountForbidTime = ga.ForbidTime
	player.Ingot = playerPropDb.GetPlayerIngot(int(player.Id))

	return player
}

func (s *toolService) MailLog(req *model.MailLogReq) ([]*model.MailLog, int) {
	m := dao.MailLog.Where(dao.MailLog.Columns.PlatformId, req.PlatformId)
	if req.StartTime > 0 {
		m = m.Where(dao.MailLog.Columns.Time+" between ? and ?", g.Slice{req.StartTime, req.EndTime})
	}
	m1 := m.Clone()
	m.M = m.M.Order(dao.MailLog.Columns.Id + " desc")
	data, err := m.Page(req.Cur, req.PNum).FindAll()
	defErr.SelectRetPanic(err, data, define.DataOptFail)
	total, err := m1.Count()
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}

	var (
		uids []int
	)
	for _, v := range data {
		uids = append(uids, v.UserId)
	}
	us := dao.MyadminUser.GetUserList(uids)
	for _, v := range data {
		if e, ok := us[v.UserId]; ok {
			v.UserName = e.Name
		}

	}
	return data, total
}

func (s *toolService) SendMail(req gamemodel.SendMailHttpRequest, uid int) {
	req.PlayerIdList = make([]int, 0)
	if req.Type == "1" {
		// 发送给单服角色
		if req.PlayerNameList != "" && len(req.NodeList) != 1 {
			defErr.Panic(define.ParamErr)
		}
		if req.PlayerNameList != "" {
			sid, _ := commonservice.GamePlayer.SplitPlayerName(req.PlayerNameList)
			node := centerservice.CGameServer.FetchNodeStrByPtIdAndSid(req.PlatformId, sid)
			req.PlayerIdList = commonservice.GamePlayer.TranPlayerNameSting2PlayerIdList(node, req.PlatformId, req.PlayerNameList)
		}
	} else if req.Type == "2" {
		// 发送给多个服
		if req.PlayerNameList != "" || len(req.NodeList) == 0 {
			defErr.Panic(define.ParamErr)
		}
	} else if req.Type == "3" {
		// 全服发送
		if req.PlayerNameList != "" || len(req.NodeList) > 0 {
			defErr.Panic(define.ParamErr)
		}
	}

	if req.ConditionsId == 1 { // vip等级
		_, err := strconv.Atoi(req.ConditionsValue)
		defErr.IfPanic(err, define.VipLevelErr)
	}
	request, err := json.Marshal(req)
	if err != nil {
		defErr.Panic(define.Fail, err.Error())
	}
	nodeList, err := json.Marshal(req.NodeList)
	if err != nil {
		defErr.Panic(define.Fail, err.Error())
	}
	itemList, err := json.Marshal(req.MailItemList)
	if err != nil {
		defErr.Panic(define.Fail, err.Error())
	}

	mailLog := &model.MailLog{
		PlatformId:     req.PlatformId,
		NodeList:       string(nodeList),
		Title:          req.Title,
		Content:        req.Content,
		Time:           int(gtime.Timestamp()),
		UserId:         uid,
		ItemList:       string(itemList),
		PlayerNameList: req.PlayerNameList,
		Type:           req.Type,
		Status:         0,
	}
	_, err = dao.MailLog.FieldsEx("userName").Save(mailLog)
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}

	realNodeList := make([]string, 0)
	if req.Type == "3" {
		realNodeList = centerservice.CGameNode.GetAllGameNodeByPlatformId(req.PlatformId)
	} else {
		gameServers, _ := centerservice.CGameServer.GetGameServerList(req.PlatformId, req.NodeList, true)
		for _, v := range gameServers {
			realNodeList = append(realNodeList, v.Node)
		}
		realNodeList = utils.RemoveRedata(realNodeList)
	}

	for _, node := range realNodeList {
		url := centerservice.CGameNode.GetGameURLByNode(node) + "/send_mail"
		data := string(request)
		utils.HttpRequest(url, data)
	}
}

func (s *toolService) GetImpactRankList(req *gamemodel.ImpactRankReq) ([]*gamemodel.PlayerImpactRank, int) {
	var (
		node   = centerservice.CGameServer.FetchNodeStrByPtIdAndSid(req.PlatformId, req.ServerId)
		gameDb = gamedao.NewPlayerImpactRank(node)
		column = gameDb.Columns
	)
	//todo curPro项目中这里查询了一个不存在的字段id
	m := gameDb.Where(gameDb.Columns.ActivityId, req.ActivityId)

	if req.PlayerId > 0 {
		m = m.Where(column.PlayerId, req.PlayerId)
	}
	m1 := m.Clone()
	m = m.Page(req.Cur, req.PNum).Order(column.Rank + " desc")
	data, err := m.FindAll()
	defErr.SelectRetPanic(err, data, define.DataOptFail)
	total, err := m1.Count()
	if err != nil {
		defErr.Panic(define.DataOptFail, err.Error())
	}

	var pids []int
	for _, v := range data {
		pids = append(pids, v.PlayerId)
	}
	playerGameDao := gamedao.NewPlayerDao(node)
	playerNames := playerGameDao.GetPlayerNames(pids)
	for _, v := range data {
		if name, ok := playerNames[v.PlayerId]; ok {
			v.PlayerName = name
		}
	}

	return data, total
}
